﻿using System;
using System.Collections;

namespace UniRx.Operators
{
	// Token: 0x020003E4 RID: 996
	internal class BatchFrameObservable : OperatorObservableBase<Unit>
	{
		// Token: 0x0600147A RID: 5242 RVA: 0x0005C349 File Offset: 0x0005A749
		public BatchFrameObservable(IObservable<Unit> source, int frameCount, FrameCountType frameCountType) : base(source.IsRequiredSubscribeOnCurrentThread<Unit>())
		{
			this.source = source;
			this.frameCount = frameCount;
			this.frameCountType = frameCountType;
		}

		// Token: 0x0600147B RID: 5243 RVA: 0x0005C36C File Offset: 0x0005A76C
		protected override IDisposable SubscribeCore(IObserver<Unit> observer, IDisposable cancel)
		{
			return new BatchFrameObservable.BatchFrame(this, observer, cancel).Run();
		}

		// Token: 0x04000BCE RID: 3022
		private readonly IObservable<Unit> source;

		// Token: 0x04000BCF RID: 3023
		private readonly int frameCount;

		// Token: 0x04000BD0 RID: 3024
		private readonly FrameCountType frameCountType;

		// Token: 0x020003E5 RID: 997
		private class BatchFrame : OperatorObserverBase<Unit, Unit>
		{
			// Token: 0x0600147C RID: 5244 RVA: 0x0005C37B File Offset: 0x0005A77B
			public BatchFrame(BatchFrameObservable parent, IObserver<Unit> observer, IDisposable cancel) : base(observer, cancel)
			{
				this.parent = parent;
				this.timer = new BatchFrameObservable.BatchFrame.ReusableEnumerator(this);
			}

			// Token: 0x0600147D RID: 5245 RVA: 0x0005C3B0 File Offset: 0x0005A7B0
			public IDisposable Run()
			{
				IDisposable disposable = this.parent.source.Subscribe(this);
				return StableCompositeDisposable.Create(disposable, this.cancellationToken);
			}

			// Token: 0x0600147E RID: 5246 RVA: 0x0005C3DC File Offset: 0x0005A7DC
			public override void OnNext(Unit value)
			{
				object obj = this.gate;
				lock (obj)
				{
					if (!this.isRunning)
					{
						this.isRunning = true;
						this.timer.Reset();
						switch (this.parent.frameCountType)
						{
						case FrameCountType.Update:
							MainThreadDispatcher.StartUpdateMicroCoroutine(this.timer);
							break;
						case FrameCountType.FixedUpdate:
							MainThreadDispatcher.StartFixedUpdateMicroCoroutine(this.timer);
							break;
						case FrameCountType.EndOfFrame:
							MainThreadDispatcher.StartEndOfFrameMicroCoroutine(this.timer);
							break;
						}
					}
				}
			}

			// Token: 0x0600147F RID: 5247 RVA: 0x0005C488 File Offset: 0x0005A888
			public override void OnError(Exception error)
			{
				try
				{
					this.observer.OnError(error);
				}
				finally
				{
					base.Dispose();
				}
			}

			// Token: 0x06001480 RID: 5248 RVA: 0x0005C4C0 File Offset: 0x0005A8C0
			public override void OnCompleted()
			{
				object obj = this.gate;
				bool flag;
				lock (obj)
				{
					flag = this.isRunning;
					this.isCompleted = true;
				}
				if (flag)
				{
					this.observer.OnNext(Unit.Default);
				}
				try
				{
					this.observer.OnCompleted();
				}
				finally
				{
					base.Dispose();
				}
			}

			// Token: 0x04000BD1 RID: 3025
			private readonly BatchFrameObservable parent;

			// Token: 0x04000BD2 RID: 3026
			private readonly object gate = new object();

			// Token: 0x04000BD3 RID: 3027
			private readonly BooleanDisposable cancellationToken = new BooleanDisposable();

			// Token: 0x04000BD4 RID: 3028
			private readonly IEnumerator timer;

			// Token: 0x04000BD5 RID: 3029
			private bool isRunning;

			// Token: 0x04000BD6 RID: 3030
			private bool isCompleted;

			// Token: 0x020003E6 RID: 998
			private class ReusableEnumerator : IEnumerator
			{
				// Token: 0x06001481 RID: 5249 RVA: 0x0005C544 File Offset: 0x0005A944
				public ReusableEnumerator(BatchFrameObservable.BatchFrame parent)
				{
					this.parent = parent;
				}

				// Token: 0x17000185 RID: 389
				// (get) Token: 0x06001482 RID: 5250 RVA: 0x0005C553 File Offset: 0x0005A953
				public object Current
				{
					get
					{
						return null;
					}
				}

				// Token: 0x06001483 RID: 5251 RVA: 0x0005C558 File Offset: 0x0005A958
				public bool MoveNext()
				{
					if (this.parent.cancellationToken.IsDisposed)
					{
						return false;
					}
					object gate = this.parent.gate;
					lock (gate)
					{
						if (this.currentFrame++ != this.parent.parent.frameCount)
						{
							return true;
						}
						if (this.parent.isCompleted)
						{
							return false;
						}
						this.parent.isRunning = false;
					}
					this.parent.observer.OnNext(Unit.Default);
					return false;
				}

				// Token: 0x06001484 RID: 5252 RVA: 0x0005C61C File Offset: 0x0005AA1C
				public void Reset()
				{
					this.currentFrame = 0;
				}

				// Token: 0x04000BD7 RID: 3031
				private readonly BatchFrameObservable.BatchFrame parent;

				// Token: 0x04000BD8 RID: 3032
				private int currentFrame;
			}
		}
	}
}
